package cn.com.dashihui.wx.controller;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.aop.Duang;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.tx.Tx;

import cn.com.dashihui.wx.common.OrderCode;
import cn.com.dashihui.wx.dao.Order;
import cn.com.dashihui.wx.dao.OrderPayAPIRecord;
import cn.com.dashihui.wx.kit.DatetimeKit;
import cn.com.dashihui.wx.kit.DoubleKit;
import cn.com.dashihui.wx.pay.wx.kit.UtilKit;
import cn.com.dashihui.wx.pay.wx.response.NoticeResData;
import cn.com.dashihui.wx.service.OrderService;

/**
 * 各个支付平台支付结果处理回调通知处理类
 */
public class OrderPayNotifyController extends BaseController {
	private static final Logger logger = LoggerFactory.getLogger(OrderPayNotifyController.class);
	OrderService orderService = Duang.duang(OrderService.class);

	/**
	 * 微信订单支付结果通知处理
	 */
	@Clear
	@Before(Tx.class)
	public void wx() {
		//获取支付平台发送的通知信息
		String returnContent = getRequestStr();
		//如果为空，则获取失败
		if(StrKit.isBlank(returnContent)){
			renderText("<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[获取支付结果通知信息失败！]]></return_msg></xml>");
			return;
		}
		//转换为对象
		NoticeResData noticeResData = (NoticeResData)UtilKit.getObjectFromXML(returnContent, NoticeResData.class);
		if(noticeResData!=null){
			//第一步验证，“返回状态码”为“SUCCESS”，且“业务结果”为“SUCCESS”
			if(noticeResData.getReturn_code().equalsIgnoreCase("SUCCESS") && noticeResData.getResult_code().equalsIgnoreCase("SUCCESS")){
				//第二步验证，通知过来的订单号是否存在
				String orderNum = noticeResData.getOut_trade_no();
				List<Order> orderList = orderService.getOrderListByMergerOrderNum(orderNum);
				//如果订单不存在，则直接返回SUCCESS，不处理
				if(orderList==null||orderList.size()<1){
					renderText("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[]]></return_msg></xml>");
					return;
				}
				//订单状态为已支付，则直接返回SUCCESS，不处理
				for(Order order : orderList){
					if(order.getInt("payType")==OrderCode.OrderPayType.ON_LINE&&order.getInt("payState")==OrderCode.OrderPayState.HAD_PAY){
						renderText("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[]]></return_msg></xml>");
						return;
					}
				}
				logger.info(returnContent);
				//记录接口记录
				new OrderPayAPIRecord()
					.set("orderNum",orderNum)
					.set("payMethod", OrderCode.OrderPayMethod.WEIXIN)
					.set("sendContent", null)
					.set("returnContent", returnContent)
					.set("flag", 2).save();
				//第三步验证，验证双方订单总金额是否一致
				double amount = 0;
				for(Order order : orderList){
					if(order.getInt("payType")==OrderCode.OrderPayType.ON_LINE){
						amount = DoubleKit.add(amount, order.getDouble("amount"));
					}
				}
				int amount_int = Double.valueOf(DoubleKit.mul(amount, 100)).intValue();
				int total_fee = Integer.valueOf(noticeResData.getTotal_fee());
				if(amount_int==total_fee){
					for(Order order : orderList){
						if(order.getInt("payType")==OrderCode.OrderPayType.ON_LINE){
							//修改订单状态为已支付，且记录微信交易订单号及支付时间
							order.set("tradeNo",noticeResData.getTransaction_id()).set("payState", OrderCode.OrderPayState.HAD_PAY).set("payDate", DatetimeKit.getFormatDate("yyyy-MM-dd HH:mm:ss")).update();
							orderService.log(order.getStr("orderNum"),OrderCode.OrderLogType.PAY,"用户", OrderCode.OrderLogType.PAY_ACTION, "订单支付成功，等待系统确认");
						}
					}
					renderText("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[]]></return_msg></xml>");
					return;
				}else{
					renderText("<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[订单金额校验错误]]></return_msg></xml>");
					return;
				}
			}
		}
	}
	
	/**
	 * 从request中获取输入流
	 */
	private String getRequestStr(){
		try {
			HttpServletRequest request = this.getRequest();
			InputStream inStream = request.getInputStream();
			ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = inStream.read(buffer)) != -1) {
				outSteam.write(buffer, 0, len);
			}
			outSteam.close();
			inStream.close();
			return new String(outSteam.toByteArray(), "utf-8");
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("接收支付结果通知内容时出错！");
		}
		return null;
	}
}
